package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.aliyun.iot20180120.Client;
import com.aliyun.iot20180120.models.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.zzyl.base.PageResponse;
import com.zzyl.constant.CacheConstants;
import com.zzyl.dto.DeviceDto;
import com.zzyl.entity.Device;
import com.zzyl.entity.DeviceData;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.DeviceMapper;
import com.zzyl.properties.AliIoTConfigProperties;
import com.zzyl.service.DeviceService;
import com.zzyl.vo.DeviceDataVo;
import com.zzyl.vo.DeviceVo;
import com.zzyl.vo.ProductVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.zzyl.enums.BasicEnum.*;

@Service
public class DeviceServiceImpl implements DeviceService {

    @Autowired
    private Client client;

    @Autowired
    private AliIoTConfigProperties aliIoTConfigProperties;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private DeviceMapper deviceMapper;
    /**
     * 同步产品列表
     */
    @Override
    public void syncProductList() {
        QueryProductListRequest request = new QueryProductListRequest();
        request.setPageSize(200);
        request.setCurrentPage(1);
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());

        QueryProductListResponse response=null;
        try {
            response = client.queryProductList(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }

        if (response.getBody()==null||!response.getBody().success){
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }

        List<QueryProductListResponseBody.QueryProductListResponseBodyDataListProductInfo> productInfo = response.getBody().getData().getList().getProductInfo();
        List<ProductVo> collect = productInfo.stream().map(p -> BeanUtil.toBean(p, ProductVo.class)).collect(Collectors.toList());
        stringRedisTemplate.opsForValue().set(CacheConstants.ALL_PRODUCT_KEY, JSON.toJSONString(collect));

    }

    /**
     * 查询所有产品列表
     *
     * @return
     */
    @Override
    public List<ProductVo> allProduct() {

//        QueryProductListRequest request = new QueryProductListRequest();
//        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
//        request.setPageSize(200);
//        request.setCurrentPage(1);
//
//        QueryProductListResponse response =null;
//        try {
//            response = client.queryProductList(request);
//        } catch (Exception e) {
//            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
//
//        }
//
//        if (!response.getBody().success){
//            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
//        }
//
////        List<ProductVo> collect = response.getBody().getData().getList().getProductInfo().stream().map(p -> BeanUtil.toBean(p, ProductVo.class)).collect(Collectors.toList());
//        QueryProductListResponseBody.QueryProductListResponseBodyData data = response.getBody().getData();
//        return response.getBody().getData();

        //TODO
        String collect = stringRedisTemplate.opsForValue().get(CacheConstants.ALL_PRODUCT_KEY);
        if (StrUtil.isBlank(collect)){
            return new ArrayList<>();
        }
        List<ProductVo> list = JSONUtil.toList(collect, ProductVo.class);
        return list;
    }

    @Override
    public void registerDevice(DeviceDto deviceDto) {
        //查询名字是否有重复
        Long count = deviceMapper.countByDeviceName(deviceDto.getDeviceName());
        if (count>0){
            throw new BaseException(DEVICE_NAME_EXIST);
        }

        //注册产品
        RegisterDeviceRequest dtoDeviceRequest = deviceDto.getRegisterDeviceRequest();
        dtoDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        RegisterDeviceResponse registerDeviceResponse=null;
        try {
            registerDeviceResponse = client.registerDevice(dtoDeviceRequest);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if (registerDeviceResponse==null || !registerDeviceResponse.getBody().getSuccess()){
            throw new BaseException(IOT_REGISTER_DEVICE_ERROR);
        }

        //查询产品
        QueryProductRequest queryProductRequest = new QueryProductRequest();
        queryProductRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        queryProductRequest.setProductKey(deviceDto.getProductKey());
        QueryProductResponse queryProductResponse=null;
        try {
            queryProductResponse = client.queryProduct(queryProductRequest);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }


        //添加到数据库
        Device device = BeanUtil.toBean(deviceDto, Device.class);
        device.setIotId(registerDeviceResponse.getBody().getData().getIotId());
        device.setProductName(queryProductResponse.getBody().getData().getProductName());


        if (device.getLocationType().equals(0)){
            device.setPhysicalLocationType(-1);
        }
        if (ObjectUtil.isEmpty(device.getHaveEntranceGuard())){
            device.setHaveEntranceGuard(0);
        }

        DeviceData deviceData = DeviceData.builder().build();
        BeanUtil.copyProperties(device,deviceData);

        try {
            deviceMapper.addDevice(device);
        } catch (Exception e) {
            DeleteDeviceRequest deleteDeviceRequest = new DeleteDeviceRequest();
            deleteDeviceRequest.setIotId(device.getIotId());
            deleteDeviceRequest.setDeviceName(device.getDeviceName());
            deleteDeviceRequest.setProductKey(device.getProductKey());
            deleteDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
            try {
                client.deleteDevice(deleteDeviceRequest);
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        }
    }


    @Override
    public PageResponse pageQueryDevice( Integer pageNum, Integer pageSize, String deviceName,Integer locationType,String productKey) {
        PageHelper.startPage(pageNum,pageSize);
        Page<DeviceVo> page=deviceMapper.list(deviceName,locationType,productKey);
        return PageResponse.of(page, DeviceDataVo.class);
    }


    @Override
    public DeviceVo QueryDeviceDetail(DeviceDto deviceDto) {
//        QueryDeviceDetailRequest queryDeviceDetailRequest = new QueryDeviceDetailRequest();
//        queryDeviceDetailRequest.setIotId(deviceDto.getIotId());
//        queryDeviceDetailRequest.setProductKey(deviceDto.getProductKey());
//        queryDeviceDetailRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
//        QueryDeviceDetailResponse response;
//        try {
//            response = client.queryDeviceDetail(queryDeviceDetailRequest);
//        } catch (Exception e) {
//            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
//        }
//        //安全校验
//        if(!response.getBody().success){
//            throw new RuntimeException(response.getBody().getErrorMessage());
//        }
//
//        //查询表中的数据
//        DeviceVo deviceVo = deviceMapper.seleteByIotId(deviceDto.getIotId());
//
//        //合并
//        QueryDeviceDetailResponseBody.QueryDeviceDetailResponseBodyData data = response.getBody().getData();
//        BeanUtil.copyProperties(data,deviceVo);
//        return deviceVo;


        QueryDeviceDetailRequest queryDeviceDetailResponse =new QueryDeviceDetailRequest();
        queryDeviceDetailResponse.setProductKey(deviceDto.getProductKey());
        queryDeviceDetailResponse.setIotId(deviceDto.getIotId());
        queryDeviceDetailResponse.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());

        QueryDeviceDetailResponse queryDeviceDetailResponse1;
        try {
            queryDeviceDetailResponse1 = client.queryDeviceDetail(queryDeviceDetailResponse);
        } catch (Exception e) {
            throw new BaseException(IOT_REGISTER_DEVICE_ERROR);
        }
        if (!queryDeviceDetailResponse1.getBody().success){
            throw new RuntimeException(queryDeviceDetailResponse1.getBody().getErrorMessage());
        }
        DeviceVo deviceVo = deviceMapper.seleteByIotId(deviceDto.iotId);
        deviceVo.setDataState(queryDeviceDetailResponse1.getBody().getData().getStatus());
        BeanUtil.copyProperties(queryDeviceDetailResponse1.getBody().getData(),deviceVo,CopyOptions.create().ignoreNullValue());
        return deviceVo;
    }


    @Override
    public QueryThingModelPublishedResponseBody.QueryThingModelPublishedResponseBodyData QueryThingModelPublished(QueryThingModelPublishedRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryThingModelPublishedResponse queryThingModelPublishedResponse;
        try {
            queryThingModelPublishedResponse= client.queryThingModelPublished(request);
        } catch (Exception e) {
            throw new BaseException(IOT_REGISTER_DEVICE_ERROR);
        }

        if (!queryThingModelPublishedResponse.getBody().success){
            throw new RuntimeException(queryThingModelPublishedResponse.getBody().getErrorMessage());
        }

        QueryThingModelPublishedResponseBody.QueryThingModelPublishedResponseBodyData data = queryThingModelPublishedResponse.getBody().getData();

        return data;
    }

    @Override
    public Object queryDevicePropertyStatus(QueryDevicePropertyStatusRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryDevicePropertyStatusResponse queryDevicePropertyStatusResponse;
        try {
            queryDevicePropertyStatusResponse = client.queryDevicePropertyStatus(request);
        } catch (Exception e) {
            throw new BaseException(IOT_REGISTER_DEVICE_ERROR);
        }
        QueryDevicePropertyStatusResponseBody.QueryDevicePropertyStatusResponseBodyData data = queryDevicePropertyStatusResponse.getBody().getData();
        return queryDevicePropertyStatusResponse.getBody().getData();
    }

    @Override
    public void updateDevice(DeviceDto deviceDto) {
        Integer number=deviceMapper.seleteById(deviceDto.getId());

//        Device dbDevice = deviceMapper.selectByPrimaryKey(deviceDto.getId());
//        if (ObjectUtil.isEmpty(dbDevice)) {
//            throw new BaseException(BasicEnum.DEVICE_NOT_EXIST);
//        }

        //调用物联网接口，更新云服务设备信息
        BatchUpdateDeviceNicknameRequest request = new BatchUpdateDeviceNicknameRequest();
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        BatchUpdateDeviceNicknameRequest.BatchUpdateDeviceNicknameRequestDeviceNicknameInfo nicknameInfo = BeanUtil.toBean(deviceDto, BatchUpdateDeviceNicknameRequest.BatchUpdateDeviceNicknameRequestDeviceNicknameInfo.class);
        request.setDeviceNicknameInfo(Lists.newArrayList(nicknameInfo));
        BatchUpdateDeviceNicknameResponse response;
        try {
            response = client.batchUpdateDeviceNickname(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_BATCH_UPDATE_DEVICE_ERROR);
        }
        if (ObjectUtil.notEqual(Boolean.TRUE, response.getBody().getSuccess())) {
            throw new BaseException(BasicEnum.IOT_BATCH_UPDATE_DEVICE_ERROR);
        }

        // 保存位置
        Device device = BeanUtil.toBean(deviceDto, Device.class);
        //如果是随身设备，物理位置设为-1


        //更新数据库中设备信息
        try {
            deviceMapper.updateDevice(device);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.RE_SELECT_PRODUCT);
        }

    }

    @Override
    public void DeleteDevice(DeleteDeviceRequest deviceRequest) {

        deviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        DeleteDeviceResponse deleteDeviceResponse;
        try {
            deleteDeviceResponse = client.deleteDevice(deviceRequest);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_DELETE_DEVICE_ERROR);
        }

        if (Boolean.TRUE.equals(deleteDeviceResponse.getBody().success)){
            deviceMapper.deleteByIotId(deviceRequest.getIotId());
            return;
        }

        throw new BaseException(IOT_DELETE_DEVICE_ERROR);

    }

    @Override
    public QueryDeviceServiceDataResponseBody.QueryDeviceServiceDataResponseBodyData pageQueryDeviceServiceData(Long endTime, Long startTime, String iotId, Integer pageSize) {

        QueryDeviceServiceDataRequest queryDeviceServiceDataRequest = new QueryDeviceServiceDataRequest();
        queryDeviceServiceDataRequest.setEndTime(endTime);
        queryDeviceServiceDataRequest.setStartTime(startTime);
        queryDeviceServiceDataRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        queryDeviceServiceDataRequest.setIotId(iotId);
        queryDeviceServiceDataRequest.setPageSize(pageSize);
        QueryDeviceServiceDataResponse queryDeviceServiceDataResponse;
        try {
            queryDeviceServiceDataResponse = client.queryDeviceServiceData(queryDeviceServiceDataRequest);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        QueryDeviceServiceDataResponseBody.QueryDeviceServiceDataResponseBodyData data = queryDeviceServiceDataResponse.getBody().getData();
        return data;
    }


}
